package com.foreknow.elm.framework;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 自定义前端控制器：主要的作用是用来拦截客户端的请求： 格式(/Controller类名/Controller中的方法名)
 * 1. 处理字符编码集
 * 2. 获取到客户发送请求的路径  http://localhost:8080/elm/Controller类名/Controller方法名
 */
@WebServlet("/")
public class DispatcherServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 服务器端向客户端响应的内容类型（MIME）
        resp.setContentType("text/html;charset=utf-8");
        // 设置客户端向服务器端发送请求的编码格式
        req.setCharacterEncoding("utf-8");
        //2. 在浏览器页面中输出内容
        PrintWriter out = resp.getWriter();
        //3. 获取url中的部分路径：  /类名/方法名
        String path = req.getServletPath();
        //4. 对path截取子串，获取到类名以及方法名
        String className = path.substring(1,path.lastIndexOf("/"));
        String methodName = path.substring(path.lastIndexOf("/")+1);
        try {
            //5. 通过反射调用Controller类中的方法
            Class clazz = Class.forName("com.foreknow.elm.controller."+className);
            Object obj = clazz.newInstance(); //实例化(创建对象)
            Method method = clazz.getMethod(methodName,HttpServletRequest.class);
            //6. 调用类中的方法
            Object result = method.invoke(obj,req);
            //7. 要将结果以json的数据格式返回给前端(JSON的转换工具 jackson-core-2.11.0.jar)
            ObjectMapper objectMapper = new ObjectMapper();
            out.println(objectMapper.writeValueAsString(result));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
